package com.itheima.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.admin.mapper.AdminRoleMapper;
import com.itheima.admin.mapper.RolePermissionRelationMapper;
import com.itheima.admin.service.RoleService;
import com.itheima.model.admin.dtos.RoleDto;
import com.itheima.model.admin.pojos.AdminRole;
import com.itheima.model.admin.pojos.RolePermissionRelation;
import com.itheima.model.admin.vos.RoleDetailVo;
import com.itheima.model.common.dtos.ResponseResult;
import com.itheima.model.common.enums.AppHttpCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色管理服务实现
 * 
 * @author itheima
 */
@Slf4j
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private AdminRoleMapper roleMapper;

    @Autowired
    private RolePermissionRelationMapper rolePermissionRelationMapper;

    @Override
    public ResponseResult listAllRoles() {
        List<AdminRole> roles = roleMapper.selectList(null);
        return ResponseResult.okResult(roles);
    }

    @Override
    public ResponseResult getRoleById(Integer id) {
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        AdminRole role = roleMapper.selectById(id);
        if (role == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "角色不存在");
        }

        // 转换为VO并查询权限列表
        RoleDetailVo vo = new RoleDetailVo();
        BeanUtils.copyProperties(role, vo);
        
        List<String> permissions = roleMapper.selectPermissionsByRoleId(id);
        vo.setPermissions(permissions);

        return ResponseResult.okResult(vo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult createRole(RoleDto dto) {
        // 检查角色编码是否已存在
        LambdaQueryWrapper<AdminRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdminRole::getRoleCode, dto.getRoleCode());
        int count = roleMapper.selectCount(wrapper).intValue();
        if (count > 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST, "角色编码已存在");
        }

        // 创建角色
        AdminRole role = new AdminRole();
        BeanUtils.copyProperties(dto, role);
        int rows = roleMapper.insert(role);
        if (rows == 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR, "创建角色失败");
        }

        // 分配权限
        if (dto.getPermissionIds() != null && !dto.getPermissionIds().isEmpty()) {
            assignPermissionsToRole(role.getId(), dto.getPermissionIds());
        }

        return ResponseResult.okResult(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult updateRole(Integer id, RoleDto dto) {
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        AdminRole role = roleMapper.selectById(id);
        if (role == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "角色不存在");
        }

        // 更新角色
        AdminRole updateRole = new AdminRole();
        updateRole.setId(id);
        BeanUtils.copyProperties(dto, updateRole);
        int rows = roleMapper.updateById(updateRole);
        if (rows == 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR, "更新角色失败");
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteRole(Integer id) {
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 不能删除超级管理员角色
        if (id == 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "不能删除超级管理员角色");
        }

        int rows = roleMapper.deleteById(id);
        if (rows == 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "角色不存在");
        }

        // 删除权限关联
        LambdaQueryWrapper<RolePermissionRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermissionRelation::getRoleId, id);
        rolePermissionRelationMapper.delete(wrapper);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult assignPermissions(Integer roleId, List<Integer> permissionIds) {
        if (roleId == null || permissionIds == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 删除旧的权限关联
        LambdaQueryWrapper<RolePermissionRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermissionRelation::getRoleId, roleId);
        rolePermissionRelationMapper.delete(wrapper);

        // 添加新的权限关联
        if (!permissionIds.isEmpty()) {
            assignPermissionsToRole(roleId, permissionIds);
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 为角色分配权限（内部方法）
     */
    private void assignPermissionsToRole(Integer roleId, List<Integer> permissionIds) {
        List<RolePermissionRelation> relations = permissionIds.stream()
                .map(permissionId -> {
                    RolePermissionRelation relation = new RolePermissionRelation();
                    relation.setRoleId(roleId);
                    relation.setPermissionId(permissionId);
                    return relation;
                })
                .collect(Collectors.toList());

        for (RolePermissionRelation relation : relations) {
            rolePermissionRelationMapper.insert(relation);
        }
    }
}

